Skip to content

[maint] Deprecate Python 3.9 due to security EOL#55

Merged
charlesbmi merged 1 commit intomainfrom
maint/deprecate-39
Dec 9, 2025
Merged

[maint] Deprecate Python 3.9 due to security EOL#55
charlesbmi merged 1 commit intomainfrom
maint/deprecate-39

Conversation

@charlesbmi
Copy link
Copy Markdown
Collaborator

Introduction

Python 3.9 reached its official end-of-life (EOL) on October 31, 2025, meaning the Python Software Foundation (PSF) stopped providing security updates and bug fixes, making it crucial for users to migrate to newer versions like Python 3.10+ to avoid security vulnerabilities and maintain library support.

https://devguide.python.org/versions/

Changes

  • Deprecate Python 3.9
  • fix lint as part of ruff now targeting Python 3.10

Behavior

Behavior on other python versions should work, pass tests.

Review checklist

  • All existing tests and checks pass
  • Unit tests covering the new feature or bugfix have been added
  • The documentation has been updated if necessary

@qodo-code-review
Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Type Narrowing

In _prepare_inputs_and_namespace the return annotation uses tuple[type[math] | _ArrayNamespace, tuple]; callers may rely on concrete tuple element types. Verify downstream usage expects a bare tuple and not specific shapes, and that isinstance checks on the first element work across both math and ArrayNamespace.

def _prepare_inputs_and_namespace(
    *inputs: Real[Array, "..."] | float | int,
) -> tuple[type[math] | _ArrayNamespace, tuple]:
Typing Consistency

The function array_namespace now returns using PEP 604 unions; ensure all internal consumers and any exported typing stubs are updated to match _ArrayNamespace | _ArrayNamespaceWithLinAlg to avoid mypy/pyright mismatches.

def array_namespace(*arrays: Any) -> _ArrayNamespace | _ArrayNamespaceWithLinAlg:
    """Typed wrapper around array_api_compat.array_namespace.
Backport Semantics

file_digest docstring and logic reference Python 3.11 API while targeting 3.10; confirm behavior matches hashlib.file_digest for edge cases (empty files, non-seekable streams) and that digest callable typing covers constructors without args.

def file_digest(fileobj, digest: str | Callable[[], "hashlib._Hash"]) -> "hashlib._Hash":
    """Return a digest object that has been updated with contents of file object.

    This is a backport-compatible implementation of hashlib.file_digest()
    that works with Python 3.10 and follows the same API as Python 3.11+.

@qodo-code-review
Copy link
Copy Markdown

PR Code Suggestions ✨

No code suggestions found for the PR.

@charlesbmi charlesbmi merged commit 418676f into main Dec 9, 2025
9 checks passed
@charlesbmi charlesbmi deleted the maint/deprecate-39 branch December 9, 2025 07:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant